ObjectMapper入门

简介

ObjectMapper是swift写的框架,旨在简化模型(Struct/Class)和JSON相互转换.

Features

  • 将JSON映射成对象
  • 将对象映射成JSON
  • 模型嵌套(模型可以在数组/字典中)
  • 支持映射时候key的转换
  • 支持结构体类型

基本使用

为了支持映射,class或者sturct只需要实现 Mapple协议.

public protocol Mappable {
    init?(_ map: Map)
    mutating func mapping(map: Map)
}

public protocol MappableCluster: Mappable {
    static func objectForMapping(map: Map) -> Mappable? //可选的方法
}

ObjectMapper使用<-来定义每个成员变量是如何映射到JSON或者从JSON映射的

struct Temperature: Mappable {
    var celsius: String?
    var fahrenheit: String?

    init?(_ map: Map) {
    }

    mutating func mapping(map: Map) {
        celsius     <- map["celsius"]
        fahrenheit  <- map["fahrenheit"]
    }
}

一旦你的类实现Mappable, 就可以方便实现模型和JSONh的相互转换

let user = Mapper<User>().map(JSONString)

将模型转换成JSON字符串:

let JSONString = Mapper().toJSONString(user, prettyPrint: true)

ObjectMapper支持的类型如下:

  • Int
  • Bool
  • Double
  • Float
  • String
  • RawRepresentable (Enums)
  • Array
  • Dictionary
  • Object
  • Array
  • Array>
  • Set
  • Dictionary
  • Dictionary>
  • Optionals of all the above
  • Implicitly Unwrapped Optionals of the above

Mappable 协议

init?(_ map: Map) {...} 方法

这个可失败构造器,可以基于模型属性序列化的优先级来对JSON验证. 如下:必须保证name有值才使初始化成功

required init?(_ map: Map){
    // check if a required "name" property exists within the JSON.
    if map["name"].value() == nil {
        return nil
    }
    if map.JSONDictionary["name"] == nil {
        return nil
    }
}

mutating func mapping(map: Map)方法

当 JSON -> 模型 时,初始化成功后会执行.

当 模型 -> JOSN 时,这是模型只会执行这个方法.

static func objectForMapping(map: Map) -> Mappable?方法

这是个可选的方法.如果实现这个方法 ,那么init?(_ map: Map)就不再执行. 这个方法的作用在于:

提供一个存在的对象缓存用于mapping

返回一个其他类型的对象(也需遵循Mappale协议),例如:你可以观察JSON去推断应该用哪种类型来进行映射. 举例

class Vehicle: Mappable {

    var type: String?

    class func objectForMapping(map: Map) -> Mappable? {
        if let type: String = map["type"].value() {
            switch type {
                case "car":
                    return Car(map)
                case "bus":
                    return Bus(map)
                default:
                    return nil
            }
        }
        return nil
    }

    required init?(_ map: Map){

    }

    func mapping(map: Map) {
        type <- map["type"]
    }
}

类型嵌套映射 (Nested Objects)

如:

"distance" : {
     "text" : "102 ft",
     "value" : 31
}

处理方法:

func mapping(map: Map) {
    distance <- map["distance.value"]
}

Nested keys 也支持访问数组里的值:

"distance" : [
    {
     "text" : "102 ft",
     "value" : 31
     }
]

处理方法:

func mapping(map: Map) {
    distance <- map["distances.0.value"] 
}

需要注意:如果你 json 的 key 包含了.,你需要进行单独处理

func mapping(map: Map) {
    identifier <- map["app.identifier", nested: false]
}

常用的转换 Custom Transforms

ObjectMapper 支持map中的常用的转换. 想实现转换,只需要创建个元组-> (map["filed_name"], transform())

birthday <- (map["birthday"], DateTransform())

上边的转换会使得JSON中的Int类型 与 NSDate 类型 相互转换.

当然我们可以实现自己的 custom transforms , 通过满足 TransformType 协议.

public protocol TransformType {
    typealias Object
    typealias JSON

    func transformFromJSON(value: AnyObject?) -> Object?
    func transformToJSON(value: Object?) -> JSON?
}

TransformOf

很多情况用TransformOf类,能快速实现Transform功能 . TransformOf

let transform = TransformOf<Int, String>(fromJSON: { (value: String?) -> Int? in 
    // transform value from String? to Int?
    return Int(value!)
}, toJSON: { (value: Int?) -> String? in
    // transform value from Int? to String?
    if let value = value {
        return String(value)
    }
    return nil
})

id <- (map["id"], transform)

更简单的写法

id <- (map["id"], TransformOf<Int, String>(fromJSON: { Int($0!) }, toJSON: { $0.map { String($0) } }))

举例: 我可以将JSON中的Int, Float等转成字符串.

let transformAnyObject = TransformOf<String, AnyObject>(fromJSON: { (value: AnyObject?) -> String? in
    if let  value = value {
        return "\(value)"
    }
    return nil

    }, toJSON: { (value: String?) -> AnyObject? in
        if let value = value {
            return value
        }
        return nil
})      ~~~` swift

    fahrenheit  <- (map["fahrenheit"], transformAnyObject) //map["fahr~~~ enheit”]

子类

实现Mappable协议的类可以很容易被继承 . 具体实现

    class Base: Mappable {
        var base: String?

        required init?(_ map: Map) {

        }

        func mapping(map: Map) {
            base <- map["base"]
        }
    }

    class Subclass: Base {
        var sub: String?

        required init?(_ map: Map) {
            super.init(map)
        }

        override func mapping(map: Map) {
            super.mapping(map)

            sub <- map["sub"]

不要忘记实现协议的初始化方法.

支持泛型 Generic Objects

ObjectMapper 支持泛型, 同样我们需要实现协议Mappabl

class Result<T: Mappable>: Mappable {
    var result: T?

    required init?(_ map: Map){

    }

    func mapping(map: Map) {
        result <- map["result"]
    }
}

let result = Mapper<Result<User>>().SON)

results matching ""

    No results matching ""